// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_NET_TIMERQUEUE_H
#define MUDUO_NET_TIMERQUEUE_H

#include <set>
#include <vector>

#include "noncopyable.h"

#include "datetime/Timestamp.h"
#include "Callbacks.h"
#include "Channel.h"

namespace learnmuduo
{

class EventLoop;
class Timer;
class TimerId;

///
/// A best efforts timer queue.
/// No guarantee that the callback will be on time.
///
class TimerQueue : noncopyable // 定时器队列，禁止拷贝
{
 public:
  TimerQueue(EventLoop* loop);
  ~TimerQueue();

  ///
  /// Schedules the callback to be run at given time,
  /// repeats if @c interval > 0.0.
  ///
  /// Must be thread safe. Usually be called from other threads.
  TimerId addTimer(const TimerCallback& cb, // 添加定时器
                   muduo::Timestamp when, // 初次触发时间
                   double interval); // 触发间隔（0 表示一次性）

  // void cancel(TimerId timerId);

 private:

  // FIXME: use unique_ptr<Timer> instead of raw pointers.
  using Entry = std::pair<muduo::Timestamp, Timer *>; // Entry：按到期时间排序的键值对
  using TimerList = std::set<Entry>; // TimerList：有序定时器集合

  // called when timerfd alarms
  void handleRead(); // timerfd可读时的回调
  // move out all expired timers
  std::vector<Entry> getExpired(muduo::Timestamp now); // 取出所有已到期定时器
  void reset(const std::vector<Entry>& expired, muduo::Timestamp now); // 处理重复定时器并重新设置下一次到期

  bool insert(Timer* timer); // 将定时器插入集合并返回是否刷新最早触发时间

  observer_ptr<EventLoop> loop_; // TimerQueue拥有EventLoop的指针,只是为了检测与所属EventLoop是否在同一线程中,
  const int timerfd_; // Linux timerfd 文件描述符
  Channel timerfdChannel_; // 监听timerfd事件的Channel
  // Timer list sorted by expiration
  TimerList timers_; // 按到期时间排序的定时器集合
};

}
#endif // MUDUO_NET_TIMERQUEUE_H
